
#ifndef AI9_LOGIC_2017_LOGICEXECUTOR_H
#define AI9_LOGIC_2017_LOGICEXECUTOR_H


#include <ActMaker/ActMaker.h>
#include <memory>
#include <Game/Game.h>
#include <string>
#include <vector>
#include <mutex>

typedef AbstractActMaker<const PlayerInfo &, Commands &, SDK::PShowInfo &> AiAbstractActMaker;
typedef NullActMaker<const PlayerInfo &, Commands &, SDK::PShowInfo &> AiNullActMaker;
typedef ActMaker<player_aiString, const PlayerInfo &, Commands &, SDK::PShowInfo &> AiActMaker;

typedef AbstractActMaker<vector<SDK::PPlayerInfo::HumanOrder>, SDK::PShowInfo&> FeedbackAbstractActMaker;
typedef NullActMaker<vector<SDK::PPlayerInfo::HumanOrder>, SDK::PShowInfo&> FeedbackNullActMaker;
typedef ActMaker<feedback_aiString, vector<SDK::PPlayerInfo::HumanOrder>, SDK::PShowInfo&> FeedbackActMaker;


class LogicExecutor {
public:
    std::shared_ptr<AiAbstractActMaker> act[2];
    std::shared_ptr<FeedbackAbstractActMaker> feedback[2];
    std::unique_ptr<Game> game;
    std::vector<std::string> pushData[2];
    Commands main_cmd;
    int main_cmd_timestamp;
    LogicExecutor();
    PlayerInfo gatherInfo(PlayerInfo& playerInfo, int playerId);
    Commands fetchCommand(int playerId);
    void fetchCommands(int PlayerId);
    void sendCommand(Commands pCommand);
    int oneRoundRun();
    void pushInfo(int playerId, std::string data);

    SDK::PShowInfo showInfo;
    std::vector<std::string> feedbackPushData[2];
    void pushInfoFeedback(int playerId, std::string data);
    void invokeFeedback(int playerId);
    std::string fetchShowInfo();
};


#endif //AI9_LOGIC_2017_LOGICEXECUTOR_H
